package wx_article_catcher

import (
	"fmt"
	"os"
	"strings"
	"sync"
	"time"
	"webDownloader/engine/base"
	"webDownloader/engine/wx_article_catcher/utils"
)

type DownloadTaskWxArticle struct {
	base.DownloadTask
	Date       int64
	Comment_id string
	Comment    string
	Context    base.Engine
}

var ch chan int

func SetThreads(t int) {
	ch = make(chan int, t)
}

func lockThread() {
	ch <- 1
}

func releaseThread() {
	<-ch
}

func (article *DownloadTaskWxArticle) Download(wg *sync.WaitGroup) {
	lockThread()
	defer releaseThread()
	defer wg.Done()
	//请求免费文章时不要用cookie，不然容易因为操作频繁挂掉
	conf := article.Context.GetConfig()
	articleContentByte := utils.WxRequest(article.Url, conf, false)

	// 文章内容的html字符串
	articleContentStr := string(articleContentByte)

	// 检测到付费按钮，是付费文章
	if strings.Contains(articleContentStr, "var isPaySubscribe = '1' * 1;") {
		fmt.Printf("当前出现付费文章【%s】，使用登录信息获取数据\r", article.FileName)
		article_content_byte := utils.WxRequest(article.Url, conf, true)
		articleContentStr = string(article_content_byte)
		if strings.Contains(articleContentStr, "var isPaid = '0' * 1;") {
			fmt.Printf("【%s】可能未付费，如果判断错误请进行反馈\n", article.FileName)
			// 没有追加keep参数，不保留未付费文章，防止批量更新时把已解锁的文章覆盖掉
			if !(*conf)["keep"].(bool) {
				return
			}
		} else {
			fmt.Printf("付费文章【%s】内容获取成功，祝您阅读愉快！\n", article.FileName)
		}
	}

	//破坏user-select样式，解除复制限制
	if strings.Contains(articleContentStr, "user-select") {
		articleContentStr = strings.ReplaceAll(articleContentStr, "user-select", "usr-select")
	}
	//隐藏赠送者，保护隐私
	if strings.Contains(articleContentStr, "class=\"pay__gift\"") {
		articleContentStr = strings.Replace(articleContentStr, "class=\"pay__gift\"", "class=\"pay__gift\" style=\"display:none;\"", 1)
	}
	//隐藏referrer，假装是通过收藏夹打开的网页,同时替换样式表，确保留言的样式正常
	articleContentStr = strings.Replace(articleContentStr, "<title>",
		"<meta name=\"referrer\" content=\"never\"><link rel=\"stylesheet\" href=\"wxMessage.css\">\n<title>", 1)
	//消除http链接
	articleContentStr = strings.ReplaceAll(articleContentStr, "data-src=\"http://", "data-src=\"https://")
	//消除懒加载
	articleContentStr = strings.ReplaceAll(articleContentStr, "data-src", "src")
	//消除对&的转义
	articleContentStr = strings.ReplaceAll(articleContentStr, "&amp;", "&")
	//消除文章时间错误
	articleContentStr = strings.Replace(articleContentStr, "f=new Date(1e3*e)", "f=new Date()", 1)
	//加入原文链接(方便检测文章是否被删除)
	articleContentStr = strings.Replace(articleContentStr, "href=\"javascript:void(0);\" id=\"js_name\"",
		"href=\""+article.Url+"\" id=\"js_name\"", 1)
	//固定协议为https
	articleContentStr = strings.ReplaceAll(articleContentStr, "=\"//res.wx.qq.com", "=\"https://res.wx.qq.com")

	//开始获取评论数据
	cmt_id_match := utils.CmtIdReg.FindAllStringSubmatch(articleContentStr, 1)

	//只有当获取到app_msg_token且文章开启评论时才能获取并插入文章
	appMsgToken := (*conf)["appMsgToken"]
	if appMsgToken != nil && len(appMsgToken.(string)) > 0 && cmt_id_match != nil {
		article.Comment_id = cmt_id_match[0][1]
		urlInfoMatch := utils.AtcUrlReg.FindAllStringSubmatch(article.Url, 1)
		if urlInfoMatch != nil {
			__biz := urlInfoMatch[0][1]
			mid := urlInfoMatch[0][2]
			idx := urlInfoMatch[0][3]
			//fmt.Println(__biz,mid,idx)
			commentUrl := fmt.Sprintf(utils.CMT_URL_FMT, mid, idx, article.Comment_id, "777", "777", "",
				"android-28", "27001543", __biz, appMsgToken)
			cmtByte := utils.WxRequest(commentUrl, conf, true)
			//fmt.Printf("%s",cmt_byte)
			cmtConvStr := utils.CmtConv(cmtByte, commentUrl, conf)
			articleContentStr = strings.Replace(articleContentStr, utils.CmtLocationRef,
				cmtConvStr+utils.CmtLocationRef, 1)
		}
	} else {
		//留言未开启，保留占位符方便后续替换
		cmtConvStr := "<!--cmt_start--><!--cmt_end-->"
		articleContentStr = strings.Replace(articleContentStr, utils.CmtLocationRef,
			cmtConvStr+utils.CmtLocationRef, 1)
	}
	if (*conf)["book"].(bool) {
		articleContentStr = utils.AsBook(articleContentStr, article.FileName)
	}
	filePath := (*conf)["savePath"].(string) + article.FileName + ".html"
	//万事俱备，只欠东风，将数据写入文件
	file, _ := os.OpenFile(filePath, os.O_RDWR|os.O_CREATE, 0666)
	file.WriteString(articleContentStr)
	file.Close()
	//先关闭文件，再修改时间，否则在win10以下的系统中修改日期不会生效
	mod_time := time.Unix(article.Date, 0)
	os.Chtimes(filePath, mod_time, mod_time)
}
